package com.umeox.watch.moto.dataservice.services;

import android.content.Intent;
import android.os.Build;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.DateUtils;
import com.umeox.moto.common.utils.FileUtils;
import com.umeox.moto.common.utils.NetUtils;
import com.umeox.moto.common.utils.StringUtils;
import com.umeox.moto.common.utils.SystemUtils;
import com.umeox.moto.mqtt.base.AError;
import com.umeox.moto.mqtt.base.ARequest;
import com.umeox.moto.mqtt.base.AResponse;
import com.umeox.moto.mqtt.request.MqttPublishRequest;
import com.umeox.watch.httpclient.core.constant.Scheme;
import com.umeox.watch.location.proto.LocationProto;
import com.umeox.watch.moto.apiclient.http.BaseApi;
import com.umeox.watch.moto.apiclient.http.FileApiWrapper;
import com.umeox.watch.moto.apiclient.http.WaasApiWrapper;
import com.umeox.watch.moto.apiclient.http.adapter.FileApiClientAdapterImpl;
import com.umeox.watch.moto.apiclient.http.callback.WaasCallback;
import com.umeox.watch.moto.apiclient.http.client.APIClientImpl;
import com.umeox.watch.moto.apiclient.http.request.WaasRequest;
import com.umeox.watch.moto.apiclient.http.response.WaasResponse;
import com.umeox.watch.moto.apiclient.model.AgentAppConfigDTO;
import com.umeox.watch.moto.apiclient.model.AgentUsedRecord;
import com.umeox.watch.moto.apiclient.model.AlbumDTO;
import com.umeox.watch.moto.apiclient.model.ChantsCountDTO;
import com.umeox.watch.moto.apiclient.model.ChantsCounterDTO;
import com.umeox.watch.moto.apiclient.model.DeviceCodeDTO;
import com.umeox.watch.moto.apiclient.model.DeviceConfigDTO;
import com.umeox.watch.moto.apiclient.model.DeviceFriendAttrDTO;
import com.umeox.watch.moto.apiclient.model.FileSignDTO;
import com.umeox.watch.moto.apiclient.model.FriendChantsCounterDTO;
import com.umeox.watch.moto.apiclient.model.FriendStepDTO;
import com.umeox.watch.moto.apiclient.model.GalleryDTO;
import com.umeox.watch.moto.apiclient.model.GetFriendsAttrDTO;
import com.umeox.watch.moto.apiclient.model.HeartRateDTO;
import com.umeox.watch.moto.apiclient.model.HolderInfoDTO;
import com.umeox.watch.moto.apiclient.model.MessageDTO;
import com.umeox.watch.moto.apiclient.model.ServerConfigDTO;
import com.umeox.watch.moto.apiclient.model.StepRankingDTO;
import com.umeox.watch.moto.apiclient.model.StoryDTO;
import com.umeox.watch.moto.apiclient.model.StoryPlayHistoryDTO;
import com.umeox.watch.moto.apiclient.model.TaskRecordDTO;
import com.umeox.watch.moto.apiclient.model.TaskRecordInfoDTO;
import com.umeox.watch.moto.apiclient.model.UserAgentDTO;
import com.umeox.watch.moto.apiclient.model.VoipTokenDTO;
import com.umeox.watch.moto.chat.proto.ChatMsgProtos;
import com.umeox.watch.moto.dataservice.BuildConfig;
import com.umeox.watch.moto.dataservice.DataProvider;
import com.umeox.watch.moto.dataservice.base.AppExecutors;
import com.umeox.watch.moto.dataservice.base.BaseApp;
import com.umeox.watch.moto.dataservice.base.LauncherManager;
import com.umeox.watch.moto.dataservice.constants.Constants;
import com.umeox.watch.moto.dataservice.constants.InternalConstant;
import com.umeox.watch.moto.dataservice.constants.MqttConstants;
import com.umeox.watch.moto.dataservice.db.AppDataBase;
import com.umeox.watch.moto.dataservice.db.dao.StoryPlayHistoryDao;
import com.umeox.watch.moto.dataservice.db.model.DeviceConfig;
import com.umeox.watch.moto.dataservice.db.model.HeartRate;
import com.umeox.watch.moto.dataservice.db.model.ServerConfig;
import com.umeox.watch.moto.dataservice.db.model.StoryPlayHistory;
import com.umeox.watch.moto.dataservice.mqtt.DataHandleManager;
import com.umeox.watch.moto.dataservice.mqtt.PayloadMessage;
import com.umeox.watch.moto.dataservice.mqtt.bean.ChatMsgBody;
import com.umeox.watch.moto.dataservice.mqtt.bean.VoipInviteBody;
import com.umeox.watch.moto.dataservice.mqtt.bean.VoipTokenBody;
import com.umeox.watch.moto.dataservice.mqtt.bean.eventbean.BaseLocation;
import com.umeox.watch.moto.dataservice.mqtt.bean.eventbean.CMDLocation;
import com.umeox.watch.moto.dataservice.mqtt.bean.eventbean.CallLocation;
import com.umeox.watch.moto.dataservice.mqtt.bean.eventbean.FreqLocation;
import com.umeox.watch.moto.dataservice.mqtt.bean.eventbean.SOSLocation;
import com.umeox.watch.moto.dataservice.mqtt.bean.eventbean.SafeZoneLocation;
import com.umeox.watch.moto.dataservice.mqtt.bean.eventbean.StepDTO;
import com.umeox.watch.moto.dataservice.mqtt.impl.MqttServiceDelegate;
import com.umeox.watch.moto.dataservice.mqtt.interfaces.IPublishListener;
import com.umeox.watch.moto.dataservice.observer.CellInfoObserver;
import com.umeox.watch.moto.dataservice.utils.ImageUtils;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import okhttp3.logging.HttpLoggingInterceptor;


public class ApiService {

    private static final String TAG = "ApiService";
    private static WaasApiWrapper apiClient;
    private static FileApiWrapper fileApiWrapper;
    private static AppExecutors appExecutors;

    private synchronized static WaasApiWrapper getApiClient() {
        if (apiClient == null) {
            apiClient = WaasApiWrapper.getInstance();
            APIClientImpl.InitializeConfig config = new APIClientImpl.InitializeConfig();
            config.appKey = BuildConfig.CLIENT_ID;
            config.appSecret = BuildConfig.CLIENT_SECRET;
            config.host = BuildConfig.FINAL_API_HOST;
            config.scheme = Scheme.HTTPS;
            config.accessToken = BaseApp.getInstance().getMmkv().decodeString(InternalConstant.KEY_ACCESS_TOKEN, "");
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> {
                Logger.d(TAG + ">>>" + message);
            });
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            config.addInterceptor(logging);
            apiClient.init(config);
            apiClient.setHostRedirect(apiEnum -> {
                final String apiHost = LauncherManager.getInstance().getAPIHost();
                return apiEnum.getType() == BaseApi.DEFINE_API ? BuildConfig.FINAL_API_HOST : apiHost;
            });
            apiClient.setTokenChangedLisenter(token -> {
                BaseApp.getInstance().getMmkv().encode(InternalConstant.KEY_ACCESS_TOKEN, token);
                Logger.w("token refresh>>>" + token);
            });
        }

        return apiClient;
    }

    public static AppExecutors getExecutor() {
        if (appExecutors == null) {
            appExecutors = new AppExecutors();
        }
        return appExecutors;
    }

    public static FileApiWrapper getFileApiWrapper() {
        if (fileApiWrapper == null) {
            fileApiWrapper = FileApiWrapper.getInstance();
            APIClientImpl.InitializeConfig config = new APIClientImpl.InitializeConfig();
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> {
                Logger.d(TAG + ">>>" + message);
            });
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            config.host = LauncherManager.getInstance().getFileHost();
            config.scheme = Scheme.HTTPS;
            config.addInterceptor(logging);
            config.adapter = new FileApiClientAdapterImpl(config.scheme, config.host);
            fileApiWrapper.setHostRedirect(() -> LauncherManager.getInstance().getFileHost());
            fileApiWrapper.init(config);
        }
        return fileApiWrapper;
    }

    public static FileApiWrapper getFileApiWrapper(FileSignDTO fileSignDTO) {
        if (fileApiWrapper == null) {
            fileApiWrapper = FileApiWrapper.getInstance();
            APIClientImpl.InitializeConfig config = new APIClientImpl.InitializeConfig();
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> {
                Logger.d(TAG + ">>>" + message);
            });
            logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
            config.host = (fileSignDTO.secure ? "https://" : "http://") + fileSignDTO.endPoint + ":" + fileSignDTO.port + fileSignDTO.uri;
            config.scheme = fileSignDTO.secure ? Scheme.HTTPS : Scheme.HTTP;
            config.addInterceptor(logging);
            config.adapter = new FileApiClientAdapterImpl(config.scheme, config.host);
            fileApiWrapper.setHostRedirect(() -> (fileSignDTO.secure ? "https://" : "http://") + fileSignDTO.endPoint + ":" + fileSignDTO.port + fileSignDTO.uri);
            fileApiWrapper.init(config);
        }
        return fileApiWrapper;
    }

    public static void getServerConfig(String deviceId) {
        getServerConfig(deviceId, null);
    }

    public static void getServerConfig(String deviceId, ApiSampleCallback<ServerConfig> callback) {
        new NetworkTask<ServerConfig, ServerConfigDTO>(getExecutor()) {

            @Override
            protected ServerConfig saveCallResult(@NonNull ServerConfigDTO item) {
                ServerConfig serverConfig = new ServerConfig();
                serverConfig.setDeviceId(deviceId);
                serverConfig.setSslSupport(item.sslSupport);
                serverConfig.setServerAddress(item.serverAddress);
                serverConfig.setServerPort(item.serverPort);
                serverConfig.setSslServerAddress(item.sslServerAddress);
                serverConfig.setSslServerPort(item.sslServerPort);
                serverConfig.setFileServerAddress(item.fileServerAddress);
                serverConfig.setFileServerPort(item.fileServerPort);
                AppDataBase.getInstance().serverConfigDao().save(serverConfig);
                Logger.d(TAG + ">>>save server config>>>" + serverConfig);
                return serverConfig;
            }

            @Override
            protected WaasResponse createCall() {
                return getApiClient().initServerConfig(deviceId);
            }

            @Override
            protected void onFetchFailed(ServerConfig data) {
                if (callback != null) {
                    callback.onResponse(false, data);
                }
            }

            @Override
            public void onSuccess(@Nullable ServerConfig data) {
                if (callback != null) {
                    callback.onResponse(true, data);
                }
            }
        };
    }

    public static void getDeviceConfig() {
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(MqttConstants.Attributes.DEVICE_CONFIG);
        MqttServiceDelegate.requestAttributes(jsonArray, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("Get DeviceConfig Success response=" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.isEmpty()) {
                    //设备数据未初始化，通知Launcher进入qrCode页面
                    DataHandleManager.getInstance().handleNotInitDevice();
                    return;
                }

                if (jsonObject.containsKey(MqttConstants.Attributes.DEVICE_CONFIG)) {
                    DeviceConfigDTO deviceConfigDTO = jsonObject.getObject(MqttConstants.Attributes.DEVICE_CONFIG, DeviceConfigDTO.class);
                    DataHandleManager.getInstance().updateDeviceConfig(deviceConfigDTO);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                MqttPublishRequest mqttPublishRequest = (MqttPublishRequest) request;
                Logger.i("Fail topic=" + mqttPublishRequest.topic + ",message=" + message.toString() + ",payloadObj = " + mqttPublishRequest.payloadObj);
            }
        });
    }

    public static void getHolderInfo() {
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(MqttConstants.Attributes.HOLDER_INFO);
        MqttServiceDelegate.requestAttributes(jsonArray, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("Get HolderInfo Success response=" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);

                if (jsonObject.containsKey(MqttConstants.Attributes.HOLDER_INFO)) {
                    HolderInfoDTO holderInfoDTO = jsonObject.getObject(MqttConstants.Attributes.HOLDER_INFO, HolderInfoDTO.class);
                    DataHandleManager.getInstance().updateHolderInfo(holderInfoDTO);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                MqttPublishRequest mqttPublishRequest = (MqttPublishRequest) request;
                Logger.i("Fail topic=" + mqttPublishRequest.topic + ",message=" + message.toString() + ",payloadObj = " + mqttPublishRequest.payloadObj);
            }
        });
    }

    public static void getDeviceConfig(String deviceId, ApiSampleCallback<DeviceConfig> callback) {

    }

    /**
     * 获取上课禁用时段设置
     */
    public static void getForbidPeriods(String deviceId) {

    }

    /**
     * 获取定位时段设置
     */
    public static void getConcernTime(String deviceId) {

    }

    /**
     * 获取运动记步信息
     */
    public static void getStepInfo(String deviceId) {

    }

    public static void uploadLocationInfo(int locReason, LocationProto.LocationDetail locationDetail, IPublishListener listener) {
        if (locationDetail == null) {
            return;
        }

        String event = null;
        Object data = null;

        String eventId = locationDetail.getEventId();
        String holderId = locationDetail.getHolderId();
        List<BaseLocation.LocationBean> locationBeanList = new ArrayList<>();
        BaseLocation.LocationBean locationBean = convert2LocationDTO(locationDetail);
        locationBeanList.add(locationBean);

        if (locReason == LocationProto.LocReason.CMD_LOCATION_VALUE) {
            event = MqttConstants.Event.CL;
            CMDLocation cmdLocation = new CMDLocation();
            cmdLocation.reqId = locationDetail.getReqId();
            cmdLocation.eventId = eventId;
            cmdLocation.holderId = holderId;
            cmdLocation.location = locationBeanList;
            data = JSONObject.toJSON(cmdLocation);
        } else if (locReason == LocationProto.LocReason.FREQUENCY_LOCATION_VALUE) {
            event = MqttConstants.Event.FL;
            FreqLocation freqLocation = new FreqLocation();
            freqLocation.locFreqId = locationDetail.getLocFreqId();
            freqLocation.eventId = eventId;
            freqLocation.holderId = holderId;
            freqLocation.location = locationBeanList;
            data = JSONObject.toJSON(freqLocation);
        } else if (locReason == LocationProto.LocReason.LOWER_BATTERY_VALUE || locReason == LocationProto.LocReason.SOS_LOCATION_VALUE) {
            event = locReason == LocationProto.LocReason.LOWER_BATTERY_VALUE ? MqttConstants.Event.LB : MqttConstants.Event.SOS;
            BaseLocation baseLocation = new BaseLocation();
            baseLocation.eventId = eventId;
            baseLocation.holderId = holderId;
            baseLocation.location = locationBeanList;
            data = JSONObject.toJSON(baseLocation);
        } else if (locReason == LocationProto.LocReason.SOS2_LOCATION_VALUE) {
            event = MqttConstants.Event.SOS2;
            SOSLocation sosLocation = new SOSLocation();
            sosLocation.sosEventId = locationDetail.getSosEventId();
            sosLocation.eventId = eventId;
            sosLocation.holderId = holderId;
            sosLocation.location = locationBeanList;
            data = JSONObject.toJSON(sosLocation);
        } else if (locReason == LocationProto.LocReason.CALL_LOCATION_VALUE) {
            event = MqttConstants.Event.PCL;
            CallLocation callLocation = new CallLocation();
            String phoneRecordInfo = locationDetail.getLocReasonAttr();
            String[] attrs = phoneRecordInfo.split("#");
            CallLocation.PhoneRecordBean phoneRecordBean = new CallLocation.PhoneRecordBean();
            phoneRecordBean.phone = attrs[0];
            phoneRecordBean.name = attrs[2];
            phoneRecordBean.callType = Integer.parseInt(attrs[1]);
            phoneRecordBean.callTime = Integer.parseInt(attrs[4]);
            phoneRecordBean.connectType = Integer.parseInt(attrs[4]) > 0 ? 1 : 0;
            callLocation.phoneRecord = phoneRecordBean;
            callLocation.eventId = eventId;
            callLocation.holderId = holderId;
            callLocation.location = locationBeanList;
            data = JSONObject.toJSON(callLocation);
        } else if (locReason == LocationProto.LocReason.POWER_OFF_LOCATION_VALUE) {
            //关机位置上报
            event = MqttConstants.Event.SD;
            BaseLocation baseLocation = new BaseLocation();
            baseLocation.eventId = eventId;
            baseLocation.holderId = holderId;
            baseLocation.location = locationBeanList;
            data = JSONObject.toJSON(baseLocation);
        }

        if (data != null) {
            MqttServiceDelegate.sendEvent(event, data, listener);
        }
    }


    public static void uploadSafeZoneEvent(List<SafeZoneLocation.FencesBean> fenceAlarmDTOList, LocationProto.LocationDetail locationDetail, IPublishListener listener) {
        if (locationDetail == null) {
            return;
        }

        String event = MqttConstants.Event.SZ;
        String eventId = locationDetail.getEventId();
        String holderId = locationDetail.getHolderId();
        List<BaseLocation.LocationBean> locationBeanList = new ArrayList<>();
        BaseLocation.LocationBean locationBean = convert2LocationDTO(locationDetail);
        locationBeanList.add(locationBean);
        SafeZoneLocation safeZoneLocation = new SafeZoneLocation();
        safeZoneLocation.fences = fenceAlarmDTOList;
        safeZoneLocation.eventId = eventId;
        safeZoneLocation.holderId = holderId;
        safeZoneLocation.location = locationBeanList;
        Object data = JSONObject.toJSON(safeZoneLocation);

        if (data != null) {
            MqttServiceDelegate.sendEvent(event, data, listener);
        }
    }

    /**
     * 上报SOS
     */
    public static void uploadSos(String deviceId, long sosId, String fileId, long times, ApiSampleCallback callback) {
    }

    /**
     * 上报SOS
     */
    public static void uploadSos(String deviceId, long sosId, String fileId, long times) {
    }

    /**
     * 上报设备记步数据
     */
    public static void uploadStepInfo(int stepCount) {
        if (TextUtils.isEmpty(DataProvider.getHolderId())) {
            return;
        }

        StepDTO stepDTO = new StepDTO();
        stepDTO.holderId = DataProvider.getHolderId();
        stepDTO.stepDate = DateUtils.getTodayDate();
        stepDTO.stepValue = stepCount;
        stepDTO.planValue = DataProvider.getPlanValue(5000);
        stepDTO.reachGoal = 0;
        JSONObject stepDTOJson = (JSONObject) JSONObject.toJSON(stepDTO);

        MqttServiceDelegate.sendEvent(MqttConstants.Event.STEP, stepDTOJson, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                Logger.d(TAG + ">>>upload step success");
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.e(TAG + ">>>upload step failed:" + error.getMsg());
            }
        });
    }


    /**
     * 上报设备记步数据
     */
    public static void reportDI() {
        JSONObject diJsonObject = new JSONObject();
        diJsonObject.put("firmwareVersion", Build.DISPLAY);
        diJsonObject.put("iccid", NetUtils.getSimCardNo());
        diJsonObject.put("mcc", Integer.valueOf(CellInfoObserver.getInstance().getMcc()));
        diJsonObject.put("mnc", Integer.valueOf(CellInfoObserver.getInstance().getMnc()));

        MqttServiceDelegate.sendEvent(MqttConstants.Event.DI, diJsonObject, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                Logger.d(TAG + ">>>report DI success");
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.e(TAG + ">>>report DI failed:" + error.getMsg());
            }
        });
    }

    /**
     * 上报设备时区
     */
    public static void updateTimeZone(String deviceId, String timeZoneId) {
    }

    /**
     * 获取闹钟列表设置
     */
    public static void getAlarmList(String deviceId) {

    }

    /**
     * 获取手表WIFI设置
     */
    public static void getWifiList(String deviceId) {
    }

    /**
     * 获取设备联系人列表
     */
    public static void getContacts() {
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(MqttConstants.Attributes.CONTACTS);
        MqttServiceDelegate.requestAttributes(jsonArray, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("获取联系人成功 response=" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                DataHandleManager.getInstance().updateData(jsonObject);
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("获取联系人失败：" + error.getMsg());
            }
        });
    }

    /**
     * 获取设备好友列表
     */
    public static void getBuddies() {
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(MqttConstants.Attributes.FRIENDS);
        MqttServiceDelegate.requestAttributes(jsonArray, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("获取好友列表成功 response=" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                DataHandleManager.getInstance().updateData(jsonObject);
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("获取好友列表失败：" + error.getMsg());
            }
        });
    }

    /**
     * 获取壁纸列表
     */
    public static void getWallpapers() {

    }

    /**
     * 刷新聊记录
     */
    public static byte[] getChatMessage(List<MessageDTO> chatMsgList) {
        ChatMsgProtos.ChatMsgs.Builder chatBuilder = ChatMsgProtos.ChatMsgs.newBuilder();
        if (chatMsgList != null && chatMsgList.size() > 0) {
            for (MessageDTO messageDTO : chatMsgList) {
                ChatMsgProtos.ChatMsg.Builder builder = ChatMsgProtos.ChatMsg.newBuilder()
                        .setMsgId(messageDTO.msgId)
                        .setFromMemberId(messageDTO.fromMemberId)
                        .setFromMemberNickname(messageDTO.fromMemberNickname)
                        .setFromMemberAvatar(messageDTO.fromMemberAvatar)
                        .setTid(messageDTO.toMemberId)
                        .setImType(ChatMsgProtos.ChatImType.forNumber(messageDTO.imType))
                        .setMsgType(ChatMsgProtos.ChatMsgType.forNumber(messageDTO.msgType))
                        .setMsgTime(messageDTO.msgTime * 1000) //服务器推送的是10位数的时间戳
                        .setMsgBody(messageDTO.msgBody);
                chatBuilder.addMsg(builder.build());
            }
            ChatMsgProtos.ChatMsgs chatMsgs = chatBuilder.build();
            if (chatMsgs != null && chatMsgs.getMsgCount() > 0) {
                return chatMsgs.toByteArray();
            }
        }
        return null;
    }

    /**
     * 发送语聊
     */
    public static String sendChatMessage(String from, String to, int type, long msgTime, int msgType, String msg) throws Exception {
        JSONObject jsonObject = new JSONObject();
        ChatMsgBody chatMsgBody = ChatMsgBody.Builder.buildChatMsg()
                .setHolderId(from)
                .setFriendId(to)
                .setType(type)
                .setMsgTime(msgTime / 1000)
                .setMsgType(msgType)
                .setMsgBody(msg).build();
        JSONObject paramsJsonObject = (JSONObject) JSONObject.toJSON(chatMsgBody);
        jsonObject.put("method", MqttConstants.ClientRpcMethod.SEND_CHAT_MSG);
        jsonObject.put("params", paramsJsonObject);

        final AtomicReference<String> result = new AtomicReference<>("");
        CountDownLatch downLatch = new CountDownLatch(1);
//        MqttServiceDelegate.sendChatMsg(jsonObject, new IPublishListener() {
//            @Override
//            public void onSuccess(ARequest request, AResponse response) {
//                String data = response.data.toString();
//                Logger.i("语聊发送成功->" + data);
//                JSONObject jsonObject = JSONObject.parseObject(data);
//                if (jsonObject.containsKey("result")) {
//                    JSONObject msgIdJsonObj = jsonObject.getJSONObject("result");
//                    result.set(msgIdJsonObj.getString("msgId"));
//
//                } else {
//                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
//                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
//                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
//                    result.set(String.valueOf(errCode));
//                }
//                downLatch.countDown();
//            }
//
//            @Override
//            public void onFailure(ARequest request, Object message, AError error) {
//                Logger.i("语聊发送失败->：" + error.getMsg());
//                downLatch.countDown();
//            }
//        });
        MqttServiceDelegate.sendChatMsg(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("语聊发送成功 ->" + data);
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("语聊发送失败->：" + error.getMsg());
                downLatch.countDown();
            }
        }, msgId -> {
            result.set(msgId);
            downLatch.countDown();
        });
        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(20, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }

    /**
     * 上传文件
     */
    public static String uploadFile(String filePath) {
        if (StringUtils.isEmpty(filePath)) {
            Logger.e(TAG + ">>>invalid parameter 'filePath'");
            return "";
        }
        File file = new File(filePath);
        if (!FileUtils.isFileExists(file)) {
            Logger.e(TAG + ">>>" + file + " not exists");
            return "";
        }
        Logger.d("开始上传文件>>>" + filePath);
        return getFileApiWrapper().uploadFile(file);
    }


    /**
     * 上传文件  （语聊文件，相册图片，SOS录音文件都会从这里上传）
     */
    public static String uploadFile(FileSignDTO fileSignDTO, String filePath) {
        Logger.e(TAG + ">>>" + fileSignDTO.toString());
        if (StringUtils.isEmpty(filePath)) {
            Logger.e(TAG + ">>>invalid parameter 'filePath'");
            return "";
        }
        File needUploadFile = null;
        File originalFile = new File(filePath);
        if (!FileUtils.isFileExists(originalFile)) {
            Logger.e(TAG + ">>>" + originalFile + " not exists");
            return "";
        }

        if (FileUtils.isImageFile(originalFile.getAbsolutePath())) {
            //文件为图片，判断是否要压缩
            String targetFilePath = FileUtils.getCompressImageCache() + "/" + originalFile.getName();
            String compressImageFilePath = ImageUtils.compressImage(originalFile.getAbsolutePath(), targetFilePath);
            Logger.e("ImageUtils", "compressImageFilePath=" + compressImageFilePath);

            needUploadFile = new File(compressImageFilePath);
        } else {
            needUploadFile = originalFile;
        }


        Logger.d("开始上传文件>>>" + filePath);
        return FileApiWrapper.getInstance().uploadSOSFile(fileSignDTO, originalFile.getName(), needUploadFile);
    }

    /**
     * 下载文件
     */
    public static boolean downloadFile(String url, String filePath) {
        if (StringUtils.isEmpty(url)) {
            Logger.e(TAG + ">>>download url is null");
            return false;
        }
        if (StringUtils.isEmpty(filePath)) {
            Logger.e(TAG + ">>>invalid parameter 'filePath'");
            return false;
        }
        File file = new File(filePath);
        if (!file.getParentFile().exists()) {
            FileUtils.createFolder(file.getParentFile().getPath());
        }
        if (!FileUtils.isFileExists(file)) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        Logger.d("开始下载文件>>>" + url);
        return FileApiWrapper.getInstance().downloadFile(url, file);
    }

    /**
     * 发送交友请求
     */
    @WorkerThread
    @SuppressWarnings("varargs")
    public static int makeFriends(String selfMac, Object[] nearByMacs) {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        paramsJsonObject.put("holderId", BaseApp.getInstance().getHolderId());
        paramsJsonObject.put("macId", selfMac);
        paramsJsonObject.put("nearByMacIds", new JSONArray(Arrays.asList(nearByMacs)));

        jsonObject.put("method", MqttConstants.ClientRpcMethod.REQUEST_FRIEND);
        jsonObject.put("params", paramsJsonObject);

        final AtomicReference<Integer> result = new AtomicReference<>(-1);
        CountDownLatch downLatch = new CountDownLatch(1);
        MqttServiceDelegate.requestFriends(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("makeFriends 请求发送成功->" + data);
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("makeFriends 请求发送失败：" + error.getMsg());
                downLatch.countDown();
            }
        }, code -> {
            result.set(code);
            downLatch.countDown();
        });

        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return result.get();
    }

    /**
     * 邀请视频电话或者语音电话
     *
     * @param type 1 视频电话 2 语音电话
     */
    @WorkerThread
    public static int inviteJoinVoipVideo(int type, String friendId, String channel) {
        JSONObject jsonObject = buildReqVoipCallBody(friendId, channel, VoipInviteBody.STATUS_CALLING, (type == 1) ? VoipInviteBody.TYPE_VIDEO_CALL : VoipInviteBody.TYPE_VOICE_CALL);
        final AtomicReference<Integer> result = new AtomicReference<>(-1);
        CountDownLatch downLatch = new CountDownLatch(1);

        MqttServiceDelegate.reqVoipCall(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("inviteJoinVideo 请求发送成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    result.set(0);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                    result.set(errCode);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("inviteJoinVideo 请求发送失败：" + error.getMsg());
                downLatch.countDown();
            }
        });
        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();

    }

    /**
     * 邀请PTT通话
     */
    @WorkerThread
    public static int inviteJoinPTT(String friendId, String channel) {
        JSONObject jsonObject = buildReqVoipCallBody(friendId, channel, VoipInviteBody.STATUS_CALLING, VoipInviteBody.TYPE_PTT_CALL);
        final AtomicReference<Integer> result = new AtomicReference<>(-1);
        CountDownLatch downLatch = new CountDownLatch(1);

        MqttServiceDelegate.reqVoipCall(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("invitePTT 请求发送成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    result.set(0);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                    result.set(errCode);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("invitePTT 请求发送失败：" + error.getMsg());
                downLatch.countDown();
            }
        });
        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();

    }

    private static JSONObject buildReqVoipCallBody(String friendId, String channel, int status, int type) {
        JSONObject jsonObject = new JSONObject();
        VoipInviteBody voipInviteBody = VoipInviteBody.Builder.aVoipIntiveBody()
                .setFromMemberId(DataProvider.getHolderId())
                .setToMemberId(friendId)
                .setChannel(channel)
                .setStatus(status)
                .setType(type)
                .build();

        JSONObject paramsJsonObject = (JSONObject) JSONObject.toJSON(voipInviteBody);
        jsonObject.put("method", MqttConstants.ClientRpcMethod.REQ_VOIP_CALL);
        jsonObject.put("params", paramsJsonObject);

        return jsonObject;
    }

    /**
     * 取消视频电话或者语音电话邀请
     *
     * @param type 1 视频电话 2 语音电话
     */
    @WorkerThread
    public static boolean notifyCancelVoipVideo(int type, String friendId, String channel) {
        JSONObject jsonObject = buildReqVoipCallBody(friendId, channel, VoipInviteBody.STATUS_CANCEL_CALL, (type == 1) ? VoipInviteBody.TYPE_VIDEO_CALL : VoipInviteBody.TYPE_VOICE_CALL);
        final AtomicBoolean result = new AtomicBoolean(false);
        CountDownLatch downLatch = new CountDownLatch(1);

        MqttServiceDelegate.reqVoipCall(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("notifyCancelVideo 请求发送成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    result.set(true);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                    result.set(false);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("notifyCancelVideo 请求发送失败：" + error.getMsg());
                result.set(false);
                downLatch.countDown();
            }
        });
        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(3, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }

    /**
     * 取消PTT邀请
     */
    @WorkerThread
    public static boolean notifyCancelPTT(String friendId, String channel) {
        JSONObject jsonObject = buildReqVoipCallBody(friendId, channel, VoipInviteBody.STATUS_CANCEL_CALL, VoipInviteBody.TYPE_PTT_CALL);
        final AtomicBoolean result = new AtomicBoolean(false);
        CountDownLatch downLatch = new CountDownLatch(1);

        MqttServiceDelegate.reqVoipCall(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("notifyCancelPTT 请求发送成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    result.set(true);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                    result.set(false);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("notifyCancelPTT 请求发送失败：" + error.getMsg());
                result.set(false);
                downLatch.countDown();
            }
        });
        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(10, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }


    /**
     * 上报视频&语言通话记录
     */
    @WorkerThread
    public static boolean uploadVideoTime(String deviceId, String friendId, String channel, long startTime, long endTime) {
        WaasResponse response = getApiClient().uploadVideoTime(deviceId, friendId, channel, startTime, endTime);
        return response != null && response.isSuccessful();
    }

    /**
     * 上传相册照片
     */
    public static void uploadAlbum(String deviceId, List<GalleryDTO> list, ApiSampleCallback<Object> callback) {
        getApiClient().uploadAlbum(deviceId, list, new WaasCallback() {
            @Override
            public void onFailure(WaasRequest waasRequest, Exception e) {
                if (callback != null) {
                    callback.onResponse(false, null);
                }
            }

            @Override
            public void onResponse(WaasRequest waasRequest, WaasResponse response) {
                if (response != null && response.isSuccessful()) {
                    if (callback != null) {
                        callback.onResponse(true, null);
                    }
                } else {
                    if (callback != null) {
                        callback.onResponse(false, null);
                    }
                }
            }
        });
    }


    private static BaseLocation.LocationBean convert2LocationDTO(LocationProto.LocationDetail detail) {
        BaseLocation.LocationBean dto;
        dto = new BaseLocation.LocationBean();
        dto.startTime = DateUtils.formatDateTime(detail.getStartTime(), "yyyyMMdd'T'HHmmssZ");
        dto.endTime = DateUtils.formatDateTime(detail.getEndTime(), "yyyyMMdd'T'HHmmssZ");
        dto.mode = detail.getLocModeValue();
        dto.order = detail.getOrder();
        dto.lat = detail.getLat();
        dto.lng = detail.getLng();
        if (detail.getAccuracy() > 0) {
            dto.accuracy = detail.getAccuracy();
        }
        if (detail.getSpeed() > 0.0) {
            dto.speed = detail.getSpeed();
        }
        dto.battery = detail.getBattery();
        dto.cellTower = detail.getCellTower();
        dto.nearByCellTowers = setNearByCellTowers(detail.getNearbyCellTowersList());
        dto.network = detail.getNetwork();
        dto.wifiPoints = setWifiPoints(detail.getWifiPointsList());
        dto.charge = detail.getCharge();
        dto.coordType = detail.getCoordType();
        dto.step = DataProvider.getStepsToday();
        return dto;
    }

    private static JSONArray setNearByCellTowers(List<String> nearByCellTowers) {
        if (nearByCellTowers != null) {
            return new JSONArray(new JSONArray(new ArrayList<>(nearByCellTowers)));
        }
        return null;
    }

    private static JSONArray setWifiPoints(List<LocationProto.WifiPoint> wifiPointList) {
        if (wifiPointList != null) {
            JSONArray jsonArray = new JSONArray(wifiPointList.size());
            for (LocationProto.WifiPoint wifiPoint : wifiPointList) {
                jsonArray.add(new JSONArray(new ArrayList<>(wifiPoint.getWifiPointList())));
            }
            Logger.e("wifiPointsJson:" + jsonArray.toJSONString());
            return jsonArray;
        }
        return null;
    }

    /**
     * 获取设备二维码，绑定码相关信息
     *
     * @return
     */
    public static void getDeviceCode() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_CODE);
        jsonObject.put("params", new JSONObject());

        MqttServiceDelegate.getDeviceCode(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("获取绑定码服务器响应结果->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    DeviceCodeDTO deviceCodeDTO = jsonObject.getObject("result", DeviceCodeDTO.class);
                    DataHandleManager.getInstance().saveOrUpdateBindCode(deviceCodeDTO);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("获取设备码失败->：" + error.getMsg());
            }
        });
    }


    /**
     * 获取设备最后位置
     *
     * @return
     */
    public static void getLastPosition() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_LAST_POSITION);
        jsonObject.put("params", new JSONObject());

        MqttServiceDelegate.getLastPosition(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("获取设备最后位置服务器响应结果->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    JSONObject resultJsonObject = jsonObject.getJSONObject("result");
                    String latitudeStr = resultJsonObject.getString("latitude");
                    String longitudeStr = resultJsonObject.getString("longitude");
                    if (!latitudeStr.equals("-999") && !longitudeStr.equals("-999")) {
                        Intent intent = new Intent(Constants.ACTION_LOCATION_SUCCESS);
                        intent.putExtra("LAT", latitudeStr);
                        intent.putExtra("LONG", longitudeStr);
                        BaseApp.getInstance().getApplicationContext().sendBroadcast(intent);
                    }


                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("获取设备最后位置->：" + error.getMsg());
            }
        });
    }


    public static VoipTokenDTO getVoipToken(String hid, String tuid, String channel) {
        JSONObject jsonObject = new JSONObject();
        VoipTokenBody voipTokenBody = VoipTokenBody.Builder.aVoipTokenBody()
                .setChannel(channel)
                .setHolderId(hid)
                .setMemberId(tuid)
                .build();

        JSONObject paramsJsonObject = (JSONObject) JSONObject.toJSON(voipTokenBody);
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_VOIP_TOKEN);
        jsonObject.put("params", paramsJsonObject);

        final AtomicReference<VoipTokenDTO> result = new AtomicReference<>(null);
        CountDownLatch downLatch = new CountDownLatch(1);

        MqttServiceDelegate.getVoipToken(jsonObject, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("getVoipToken成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    VoipTokenDTO voipTokenDTO = jsonObject.getObject("result", VoipTokenDTO.class);
                    result.set(voipTokenDTO);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("getVoipToken失败：" + error.getMsg());
                downLatch.countDown();
            }
        });

        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }

    /**
     * 获取属性
     *
     * @param params
     */
    public static void requestAttributes(List<String> params) {
        if (params == null || params.isEmpty()) {
            return;
        }
        JSONArray jsonArray = new JSONArray();
        jsonArray.addAll(params);
        MqttServiceDelegate.requestAttributes(jsonArray, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("requestAttributes Success response=" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                DataHandleManager.getInstance().updateData(jsonObject);
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("requestAttributes Fail ,AError=" + error.getMsg());
            }
        });
    }

    public static void uploadHeartRate(String code, long startTime, long endTime, int avgValue, int minValue, int maxValue) {

        HeartRateDTO heartRateDTO = new HeartRateDTO();
        heartRateDTO.code = code;
        heartRateDTO.startTime = DateUtils.formatDateTime(startTime, "yyyyMMdd'T'HHmmssZ");
        heartRateDTO.endTime = DateUtils.formatDateTime(endTime, "yyyyMMdd'T'HHmmssZ");
        heartRateDTO.avgValue = avgValue;
        heartRateDTO.minValue = minValue;
        heartRateDTO.maxValue = maxValue;
        List<HeartRateDTO> list = new ArrayList<>();
        list.add(heartRateDTO);
        JSONObject jsonObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        jsonArray.addAll(list);
        jsonObject.put("holderId", DataProvider.getHolderId());
        jsonObject.put("heartRate", jsonArray);

        MqttServiceDelegate.sendEvent(MqttConstants.Event.HR, jsonObject, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                Logger.i("上传心率>>>>请求发送成功");
                HeartRate currentData = AppDataBase.getInstance().heartRateDao().query(endTime);
                if (currentData != null) {
                    currentData.isUpload = true;
                    AppDataBase.getInstance().heartRateDao().save(currentData);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("上传心率>>>>请求发送失败：" + error.getMsg());
            }
        });

    }

    public static void getHotVer() {
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(MqttConstants.Attributes.HOT_VER);
        MqttServiceDelegate.requestAttributes(jsonArray, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("requestAttributes Success response=" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.isEmpty()) {
                    Logger.i("设备还未初始化，通知Launcher进入二维码界面");
                    DataHandleManager.getInstance().handleNotInitDevice();
                } else {
                    JSONObject versionJsonObject = jsonObject.getJSONObject(MqttConstants.Attributes.HOT_VER);
                    DataHandleManager.getInstance().updateLocalVersion(versionJsonObject);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("requestAttributes Fail ,AError=" + error.getMsg());
            }
        });
    }

    public static void uploadHotVer(JSONObject attrVerJsonObj) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(MqttConstants.Attributes.HOT_VER_C, attrVerJsonObj);
        MqttServiceDelegate.uploadHotVer(jsonObject, new IPublishListener() {

            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("uploadHotVer 请求发送成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                if (errCode == 0) {
                    Logger.i("ApiService", "uploadHotVer上报成功");
                } else {
                    Logger.e("ApiService", "uploadHotVer上报失败：" + errMsg);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("uploadHotVer失败：" + error.getMsg());
            }
        });
    }

    public static void uploadALB(List<GalleryDTO> fileUrls, IPublishListener listener) {
        if (fileUrls == null) {
            return;
        }
        List<AlbumDTO> alarmDTOList = new ArrayList<>(fileUrls.size());
        for (GalleryDTO galleryDTO : fileUrls) {
            alarmDTOList.add(new AlbumDTO(galleryDTO.imageUrl, DateUtils.formatDateTime(galleryDTO.uploadTime, "yyyyMMdd'T'HHmmssZ")));
        }

        JSONObject paramsJsonObj = new JSONObject();
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(alarmDTOList));
        paramsJsonObj.put("holderId", DataProvider.getHolderId());
        paramsJsonObj.put("files", jsonArray);
        MqttServiceDelegate.sendEvent(MqttConstants.Event.ALB, paramsJsonObj, listener);
    }

    public static void uploadChallengeRecord(int sportChallengeId, int sportType, String startTime, String endTime, int totalTime, int rewardValue, IPublishListener listener) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("holderId", BaseApp.getInstance().getHolderId());
        jsonObject.put("sportChallengeId", sportChallengeId);
        jsonObject.put("sportType", sportType);
        jsonObject.put("startTime", startTime);
        jsonObject.put("endTime", endTime);
        jsonObject.put("totalTime", totalTime);
        jsonObject.put("rewardValue", rewardValue);

        MqttServiceDelegate.sendEvent(MqttConstants.Event.SC, jsonObject, listener);
    }


    public static void uploadQuranChallengeRecord(int quranLearnId, int chapterIndex, String finishTime, int duration, int rewardValue, IPublishListener listener) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("holderId", BaseApp.getInstance().getHolderId());
        jsonObject.put("quranLearnId", quranLearnId);
        jsonObject.put("chapterIndex", chapterIndex);
        jsonObject.put("finishTime", finishTime);
        jsonObject.put("duration", duration);
        jsonObject.put("rewardValue", rewardValue);

        MqttServiceDelegate.sendEvent(MqttConstants.Event.QL, jsonObject, listener);
    }

    public static void uploadChants(List<ChantsCountDTO> chantsCountDTOList, IPublishListener listener) {
        JSONObject paramsJsonObj = new JSONObject();
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(chantsCountDTOList));
        paramsJsonObj.put("type", 1);
        paramsJsonObj.put("data", jsonArray);
        MqttServiceDelegate.sendEvent(MqttConstants.Event.CCU, paramsJsonObj, listener);
    }


    public static List<StoryDTO> getStoriesPage() {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        paramsJsonObject.put("current", 1);
        paramsJsonObject.put("size", 1000);

        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_STORIES_PAGE);
        jsonObject.put("params", paramsJsonObject);

        final AtomicReference<List<StoryDTO>> result = new AtomicReference<>(null);
        CountDownLatch downLatch = new CountDownLatch(1);
        MqttServiceDelegate.getStoriesPage(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("getStoriesPage成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    JSONObject resultJsonObject = jsonObject.getJSONObject("result");
                    JSONArray jsonArray = resultJsonObject.getJSONArray("records");
                    String jsonStr = JSONObject.toJSONString(jsonArray);
                    List<StoryDTO> storyDTOList = JSONObject.parseArray(jsonStr, StoryDTO.class);
                    result.set(storyDTOList);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("getStoriesPage失败：" + error.getMsg());
                downLatch.countDown();
            }
        });

        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }


    public static List<StoryDTO> getRecommendStories() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_RECOMMEND_STORIES);
        jsonObject.put("params", new JSONObject());

        final AtomicReference<List<StoryDTO>> result = new AtomicReference<>(null);
        CountDownLatch downLatch = new CountDownLatch(1);
        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("getRecommendStories成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    JSONObject resultJsonObject = jsonObject.getJSONObject("result");
                    JSONArray jsonArray = resultJsonObject.getJSONArray("records");
                    String jsonStr = JSONObject.toJSONString(jsonArray);
                    List<StoryDTO> storyDTOList = JSONObject.parseArray(jsonStr, StoryDTO.class);
                    result.set(storyDTOList);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("getRecommendStories失败：" + error.getMsg());
                downLatch.countDown();
            }
        });

        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }


    public static void uploadStoryPlayHistory() {
        StoryPlayHistoryDao storyPlayHistoryDao = AppDataBase.getInstance().storyPlayHistoryDao();
        List<StoryPlayHistory> storyPlayHistoryList = storyPlayHistoryDao.queryAllUnUploadHistory();
        if (storyPlayHistoryList != null && !storyPlayHistoryList.isEmpty()) {
            List<StoryPlayHistoryDTO> storyPlayHistoryDTOList = new ArrayList<>();
            for (StoryPlayHistory storyPlayHistory : storyPlayHistoryList) {
                storyPlayHistoryDTOList.add(new StoryPlayHistoryDTO(storyPlayHistory.id, storyPlayHistory.amount));
            }

            JSONObject paramsJsonObj = new JSONObject();
            JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(storyPlayHistoryDTOList));
            paramsJsonObj.put("type", 1);
            paramsJsonObj.put("details", jsonArray);
            MqttServiceDelegate.sendEvent(MqttConstants.Event.SPH, paramsJsonObj, new IPublishListener() {
                @Override
                public void onSuccess(ARequest request, AResponse response) {
                    Logger.i("上报SPH事件成功");
                    List<StoryPlayHistory> needUpdatePlayHistoryList = new ArrayList<>();
                    for (StoryPlayHistory storyPlayHistory : storyPlayHistoryList) {
                        storyPlayHistory.amount = 0;
                        needUpdatePlayHistoryList.add(storyPlayHistory);
                    }
                    storyPlayHistoryDao.save(needUpdatePlayHistoryList);
                }

                @Override
                public void onFailure(ARequest request, Object message, AError error) {
                    Logger.i("上报SPH事件失败");
                }
            });
        }
    }

    public static StepRankingDTO getStepRanking() {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_STEP);
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        paramsJsonObject.put("date", sdf.format(calendar.getTime()));
        paramsJsonObject.put("includeSurpassScale", true);
        paramsJsonObject.put("includeFriendsStep", true);
        jsonObject.put("params", paramsJsonObject);

        final AtomicReference<StepRankingDTO> result = new AtomicReference<>(null);
        CountDownLatch downLatch = new CountDownLatch(1);
        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("getStepRanking成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    JSONObject resultJsonObject = jsonObject.getJSONObject("result");
                    if (resultJsonObject.containsKey("friendsStep")) {
                        StepRankingDTO stepRankingDTO = new StepRankingDTO();
                        //获取friendStep
                        JSONArray jsonArray = resultJsonObject.getJSONArray("friendsStep");
                        String jsonStr = JSONObject.toJSONString(jsonArray);
                        stepRankingDTO.friendsStep = JSONObject.parseArray(jsonStr, FriendStepDTO.class);
                        //获取step
                        stepRankingDTO.step = resultJsonObject.getIntValue("step");
                        //获取stepPlan
                        stepRankingDTO.stepPlan = resultJsonObject.getIntValue("stepPlan");
                        //获取surpassScale
                        stepRankingDTO.surpassScale = resultJsonObject.getIntValue("surpassScale");
                        result.set(stepRankingDTO);
                    } else {
                        Logger.e("ApiService", "getStepRanking数据解析失败");
                    }
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("getStepRanking失败：" + error.getMsg());
                downLatch.countDown();
            }
        });

        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }

    public static TaskRecordInfoDTO getTaskRecord() {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_TASK_RECORD);
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        paramsJsonObject.put("holderId", BaseApp.getInstance().getHolderId());
        paramsJsonObject.put("currentTime", sdf.format(calendar.getTime()));
        jsonObject.put("params", paramsJsonObject);

        final AtomicReference<TaskRecordInfoDTO> result = new AtomicReference<>(null);
        CountDownLatch downLatch = new CountDownLatch(1);
        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("getTaskRecord成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    JSONObject resultJsonObject = jsonObject.getJSONObject("result");
                    if (resultJsonObject.containsKey("details")) {
                        TaskRecordInfoDTO taskRecordInfoDTO = new TaskRecordInfoDTO();
                        //获取friendStep
                        JSONArray jsonArray = resultJsonObject.getJSONArray("details");
                        String jsonStr = JSONObject.toJSONString(jsonArray);
                        taskRecordInfoDTO.details = JSONObject.parseArray(jsonStr, TaskRecordDTO.class);
                        //获取requestId
                        taskRecordInfoDTO.requestId = resultJsonObject.getString("requestId");
                        result.set(taskRecordInfoDTO);
                    } else {
                        Logger.e("ApiService", "getTaskRecord数据解析失败");
                    }
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("getTaskRecord失败：" + error.getMsg());
                downLatch.countDown();
            }
        });

        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }

    public static ChantsCounterDTO getChantsCounter() {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_CHANTS_COUNTER);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        paramsJsonObject.put("includeFriendsTotal", true);
        jsonObject.put("params", paramsJsonObject);

        final AtomicReference<ChantsCounterDTO> result = new AtomicReference<>(null);
        CountDownLatch downLatch = new CountDownLatch(1);
        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("getChantsCounter成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    JSONObject resultJsonObject = jsonObject.getJSONObject("result");
                    if (resultJsonObject.containsKey("friendsTotal")) {
                        ChantsCounterDTO chantsCounterDTO = new ChantsCounterDTO();
                        //获取friendStep
                        JSONArray jsonArray = resultJsonObject.getJSONArray("friendsTotal");
                        String jsonStr = JSONObject.toJSONString(jsonArray);
                        chantsCounterDTO.friendsTotal = JSONObject.parseArray(jsonStr, FriendChantsCounterDTO.class);
                        result.set(chantsCounterDTO);
                    } else {
                        Logger.e("ApiService", "getChantsCounter数据解析失败");
                    }
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("getChantsCounter失败：" + error.getMsg());
                downLatch.countDown();
            }
        });

        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }

    public static GetFriendsAttrDTO getFriendsAttr() {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_FRIENDS_ATTR);
        paramsJsonObject.put("holderId", BaseApp.getInstance().getHolderId());
        List<Integer> typeList = new ArrayList<>();
        typeList.add(1);
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(typeList));
        paramsJsonObject.put("types", jsonArray);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        jsonObject.put("params", paramsJsonObject);

        final AtomicReference<GetFriendsAttrDTO> result = new AtomicReference<>(null);
        CountDownLatch downLatch = new CountDownLatch(1);
        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("getFriendsAttr成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    JSONObject resultJsonObject = jsonObject.getJSONObject("result");
                    if (resultJsonObject.containsKey("records")) {
                        GetFriendsAttrDTO getFriendsAttrDTO = new GetFriendsAttrDTO();
                        //获取friendStep
                        JSONArray jsonArray = resultJsonObject.getJSONArray("records");
                        String jsonStr = JSONObject.toJSONString(jsonArray);
                        getFriendsAttrDTO.records = JSONObject.parseArray(jsonStr, DeviceFriendAttrDTO.class);
                        result.set(getFriendsAttrDTO);
                    } else {
                        Logger.e("ApiService", "getFriendsAttr数据解析失败");
                    }
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("getFriendsAttr失败：" + error.getMsg());
                downLatch.countDown();
            }
        });

        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }

    public static void createGroup(String groupName, List<String> friendIds) {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.CREATE_GROUP);
        paramsJsonObject.put("holderId", BaseApp.getInstance().getHolderId());
        paramsJsonObject.put("groupName", groupName);
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(friendIds));
        paramsJsonObject.put("friendIds", jsonArray);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        jsonObject.put("params", paramsJsonObject);

        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("createGroup成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (!jsonObject.containsKey("result")) {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("createGroup失败：" + error.getMsg());
            }
        });
    }

    public static void updateGroup(String groupId, String groupName) {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.UPDATE_GROUP);
        paramsJsonObject.put("holderId", BaseApp.getInstance().getHolderId());
        paramsJsonObject.put("groupId", groupId);
        paramsJsonObject.put("groupName", groupName);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        jsonObject.put("params", paramsJsonObject);

        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("updateGroup成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (!jsonObject.containsKey("result")) {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("updateGroup失败：" + error.getMsg());
            }
        });
    }

    public static void inviteJoinGroup(String groupId, List<String> friendIds) {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.INVITE_JOIN_GROUP);
        paramsJsonObject.put("holderId", BaseApp.getInstance().getHolderId());
        paramsJsonObject.put("groupId", groupId);
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(friendIds));
        paramsJsonObject.put("friendIds", jsonArray);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        jsonObject.put("params", paramsJsonObject);

        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("inviteJoinGroup成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (!jsonObject.containsKey("result")) {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("inviteJoinGroup失败：" + error.getMsg());
            }
        });
    }

    public static void removeGroupMember(String groupId, List<String> friendIds) {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.REMOVE_GROUP_MEMBER);
        paramsJsonObject.put("holderId", BaseApp.getInstance().getHolderId());
        paramsJsonObject.put("groupId", groupId);
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(friendIds));
        paramsJsonObject.put("friendIds", jsonArray);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        jsonObject.put("params", paramsJsonObject);

        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("removeGroupMember成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (!jsonObject.containsKey("result")) {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("removeGroupMember失败：" + error.getMsg());
            }
        });
    }

    public static void quitGroup(String groupId) {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.QUIT_GROUP);
        paramsJsonObject.put("holderId", BaseApp.getInstance().getHolderId());
        paramsJsonObject.put("groupId", groupId);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        jsonObject.put("params", paramsJsonObject);

        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("quitGroup成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (!jsonObject.containsKey("result")) {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("quitGroup失败：" + error.getMsg());
            }
        });
    }

    public static UserAgentDTO getAgentUser(String appKey, String agentId, String userId) {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_AGENT_USER);
        paramsJsonObject.put("appKey", appKey);
        paramsJsonObject.put("agentId", agentId);
        paramsJsonObject.put("userId", userId);
        paramsJsonObject.put("locale", SystemUtils.getLocale());
        paramsJsonObject.put("timeZone", TimeZone.getDefault().getID());
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        jsonObject.put("params", paramsJsonObject);

        final AtomicReference<UserAgentDTO> result = new AtomicReference<>(null);
        CountDownLatch downLatch = new CountDownLatch(1);
        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("getUserAgent成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    JSONObject resultJsonObject = jsonObject.getJSONObject("result");
                    UserAgentDTO userAgentDTO = new UserAgentDTO();
                    userAgentDTO.userId = resultJsonObject.getString("userId");
                    userAgentDTO.agentId = resultJsonObject.getString("agentId");
                    userAgentDTO.apiType = resultJsonObject.getString("apiType");
                    userAgentDTO.token = resultJsonObject.getString("token");
                    userAgentDTO.url = resultJsonObject.getString("url");
                    result.set(userAgentDTO);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("getUserAgent失败：" + error.getMsg());
                downLatch.countDown();
            }
        });

        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }

    public static AgentAppConfigDTO getAgentAppConfig(String appKey, String userId, int type) {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.GET_AGENT_APP_CONFIG);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        paramsJsonObject.put("appKey", appKey);
        paramsJsonObject.put("userId", userId);
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
        paramsJsonObject.put("currentTime", sdf.format(calendar.getTime()));
        paramsJsonObject.put("type", type);
        jsonObject.put("params", paramsJsonObject);

        final AtomicReference<AgentAppConfigDTO> result = new AtomicReference<>(null);
        CountDownLatch downLatch = new CountDownLatch(1);
        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("getAgentAppConfig成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (jsonObject.containsKey("result")) {
                    JSONObject resultJsonObject = jsonObject.getJSONObject("result");
                    AgentAppConfigDTO agentAppConfigDTO = new AgentAppConfigDTO();
                    agentAppConfigDTO.requestId = resultJsonObject.getString("requestId");
                    agentAppConfigDTO.limit = resultJsonObject.getInteger("limit");
                    agentAppConfigDTO.used = resultJsonObject.getInteger("used");
                    result.set(agentAppConfigDTO);
                } else {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
                downLatch.countDown();
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("getAgentAppConfig失败：" + error.getMsg());
                downLatch.countDown();
            }
        });

        if (downLatch.getCount() > 0) {
            try {
                downLatch.await(15, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return result.get();
    }

    public static void submitAgentUsedRecord(String appKey, String userId, List<AgentUsedRecord> details) {
        JSONObject jsonObject = new JSONObject();
        JSONObject paramsJsonObject = new JSONObject();
        jsonObject.put("method", MqttConstants.ClientRpcMethod.SUBMIT_AGENT_USED_RECORD);
        paramsJsonObject.put("requestId", UUID.randomUUID().toString());
        paramsJsonObject.put("appKey", appKey);
        paramsJsonObject.put("userId", userId);
        JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(details));
        paramsJsonObject.put("details", jsonArray);
        jsonObject.put("params", paramsJsonObject);

        MqttServiceDelegate.getRecommendStories(jsonObject, new IPublishListener() {
            @Override
            public void onSuccess(ARequest request, AResponse response) {
                String data = response.data.toString();
                Logger.i("submitAgentUsedRecord成功->" + data);
                JSONObject jsonObject = JSONObject.parseObject(data);
                if (!jsonObject.containsKey("result")) {
                    int errCode = jsonObject.getIntValue(PayloadMessage.ERR_CODE);
                    String errMsg = jsonObject.getString(PayloadMessage.ERR_MSG);
                    Logger.e("ApiService", "ERR_CODE->" + errCode + ",ERR_MSG->" + errMsg);
                }
            }

            @Override
            public void onFailure(ARequest request, Object message, AError error) {
                Logger.i("submitAgentUsedRecord失败：" + error.getMsg());
            }
        });
    }
}
